//
//  FavouriteViewController.swift
//  FeastBooking
//
//  Created by Imon on 2017/11/15.
//  Copyright © 2017年 Imon. All rights reserved.
//

import UIKit
import IGListKit
import RxSwift
import ReachabilitySwift

class FavouriteViewController: UIViewController {
    
    fileprivate let activityView: UIActivityIndicatorView = {
        let view = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        view.startAnimating()
        return view
    }()
    
    var checkLoadTimes = 0
    
    let reachability = Reachability()
    
    let authManager = AuthManager.share
    var favouriteVM: FavouriteViewModel?
    let restaurantVM = RestaurantViewModel.share
    
    let pageNum: Int = 10
    
    lazy var items: [ListDiffable] = []
    
    let disposeBag = DisposeBag()
    
    var restaurants: [RestaurantSummaryResponse] = []
    var page: Int = 0
    var isEnd = false
    
    var timer: Timer = Timer()
    
    var loading = false
    let spinToken = "spinner"
    
    let collectionView: UICollectionView = {
        let view = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout())
        view.backgroundColor = lightSaperatorColor
        return view
    }()
    
    lazy var adapter: ListAdapter = {
        return ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 0)
    }()
    
    let endingView: EndingView = {
        let ev = EndingView()
        return ev
    }()
    
    let emptyView: EmptyView = {
        let ev = EmptyView()
        return ev
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = LanguageHelper.getString(key: "FAVOURITE_LIST")
        setBackBarItem()
        
        initVM()
        activityView.startAnimating()
        
        view.addSubview(collectionView)
        adapter.dataSource = self
        adapter.collectionView = collectionView
        collectionView.alwaysBounceVertical = true
        
        emptyView.delegate = self
        self.view.addSubview(activityView)
        
//        if (reachability?.isReachable)! {
//            loadData()
//            timer = Foundation.Timer.scheduledTimer(timeInterval: 0.8, target: self, selector: #selector(checkDataLoad), userInfo: nil, repeats: true)
//        } else {
//            activityView.stopAnimating()
//            collectionView.removeFromSuperview()
//            self.view.addSubview(emptyView)
//            self.showPromptView(message: LanguageHelper.getString(key: "UNREACHABLE"), confirmText: LanguageHelper.getString(key: "OK"))
//        }
    }
    
    func initVM() {
        let authManager = AuthManager.share
        if authManager.hasLogined() {
            if let token = authManager.getToken() as? String {
                favouriteVM = FavouriteViewModel(token: token)
            }
        }
    }
    
    func checkDataLoad() {
        checkLoadTimes += 1
        if restaurants.count > 0 {
            activityView.stopAnimating()
            
            for restaurant in restaurants {
                items.append(restaurant as ListDiffable)
            }
            adapter.performUpdates(animated: true, completion: nil)
            
            timer.invalidate()
            adapter.scrollViewDelegate = self
        } else if checkLoadTimes > 5 {
            self.finishLoading()
        }
    }
    
    func loadData() {
        items = []
        restaurants = []
        page = 0
        checkLoadTimes = 0
        adapter.performUpdates(animated: true, completion: nil)
        adapter.scrollViewDelegate = nil
        activityView.startAnimating()
        view.insertSubview(collectionView, belowSubview: activityView)
        favouriteVM?.getFavouritesRestaurants(page: page).subscribe(onNext: { [unowned self] rests in
            for rest in rests {
                self.restaurants.append(rest)
            }
            if rests.count == self.pageNum {
                self.isEnd = false
            } else {
                self.isEnd = true
            }
            if rests.count == 0 {
                self.finishLoading()
            }
        })
        .addDisposableTo(disposeBag)
        self.page += 1
    }
    
    func finishLoading() {
        timer.invalidate()
        activityView.stopAnimating()
        collectionView.removeFromSuperview()
        self.view.addSubview(emptyView)
//        adapter.scrollViewDelegate = self
    }
    
    override func viewWillAppear(_ animated: Bool) {
        if (reachability?.isReachable)! {
            loadData()
            timer = Foundation.Timer.scheduledTimer(timeInterval: 0.8, target: self, selector: #selector(checkDataLoad), userInfo: nil, repeats: true)
        } else {
            activityView.stopAnimating()
            collectionView.removeFromSuperview()
            self.view.addSubview(emptyView)
            self.showPromptView(message: LanguageHelper.getString(key: "UNREACHABLE"), confirmText: LanguageHelper.getString(key: "OK"))
        }
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        collectionView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
        emptyView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
        activityView.center = CGPoint(x: collectionView.frame.width/2.0, y: collectionView.frame.height/2.0)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    /*
     // MARK: - Navigation
     
     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     // Get the new view controller using segue.destinationViewController.
     // Pass the selected object to the new view controller.
     }
     */
    
//    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//        if let touch = touches.first {
//            let point = touch.location(in: self.view)
//        }
//    }        
}

extension FavouriteViewController: ListAdapterDataSource {
    func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
        var objects = items as [ListDiffable]
        
        if loading {
            objects.append(spinToken as ListDiffable)
        }
        
        return objects
    }
    func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
        switch object {
        case is String:
            return spinnerSectionController()
        default:
            let sectionController = RestaurantSectionController()
            sectionController.delegate = self
            return sectionController
        }
    }
    func emptyView(for listAdapter: ListAdapter) -> UIView? {
        return nil
    }
}

extension FavouriteViewController: UIScrollViewDelegate {
    //下拉加载更多
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let distance = scrollView.contentSize.height - (targetContentOffset.pointee.y + scrollView.bounds.height)
        if !loading && !isEnd && distance < 150 {
            loading = true
            adapter.performUpdates(animated: true, completion: nil)
            DispatchQueue.global(qos: .default).async {
                sleep(2)
                self.favouriteVM?.getFavouritesRestaurants(page: self.page).subscribe(onNext: { rests in
                    for rest in rests {
                        //self.restaurants.append(rest)
                        self.items.append(rest as ListDiffable)
                    }
                    self.adapter.performUpdates(animated: true, completion: nil)
                    if rests.count == self.pageNum {
                        self.isEnd = false
                    } else {
                        self.isEnd = true
                    }
                })
                    .addDisposableTo(self.disposeBag)
                self.page += 1
                DispatchQueue.main.async {
                    //加载更多
                    self.loading = false
                }
            }
        } else if isEnd {
            self.endingView.frame = CGRect(x: 0, y: self.collectionView.contentSize.height + 10, width: self.view.frame.width, height: 25)
            self.collectionView.addSubview(self.endingView)
        }
    }
}

extension FavouriteViewController: RestaurantCollectionSectionDelegate {
    
    func detailPage(of restaurant: RestaurantSummaryResponse!) {
        restaurantVM.getRestaurant(id: restaurant.id!).subscribe(onNext: { restaurant in
            if let status = restaurant.status, status != 200 {
                self.showPromptView(message: LanguageHelper.getString(key: "ERROR_OCCUR"), confirmText: LanguageHelper.getString(key: "OK"))
            } else {
                let detailPage = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "RestaurantDetailViewController") as! RestaurantDetailViewController
                detailPage.restaurant = restaurant
                detailPage.hidesBottomBarWhenPushed = true
                self.navigationController?.pushViewController(detailPage, animated: true)
            }
        })
        .addDisposableTo(disposeBag)
    }
}

extension FavouriteViewController: EmptyViewDelegate {
    
    func reload() {
        emptyView.removeFromSuperview()
        self.loadData()
        timer = Foundation.Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(checkDataLoad), userInfo: nil, repeats: true)
    }
}
